using Jupiter.Infrastructure.Attributes;
using Jupiter.Infrastructure.Cache.Interfaces;
using Jupiter.Infrastructure.Domain.SqlSugar;
using Jupiter.Infrastructure.Exceptions;
using Jupiter.Infrastructure.Permission;
using Jupiter.Infrastructure.Permission.DataPermissions;
using Jupiter.Infrastructure.Responses;
using Microsoft.Extensions.Configuration;
using Wips.AppService.Authorities.Positions;
using Wips.AppService.Authorities.Positions.Requests;
using Wips.AppService.Authorities.Positions.Responses;
using Wips.AppService.CommonViewModels;
using Wips.Domain.Models.Authorities.Model;

namespace Wips.AppService.SqlSugar.Authorities.Positions
{
    /// <summary>
    /// 职位服务接口实现类
    /// </summary>
    [ServiceComponent]
    public class PositionService : BaseQueryAppService<Position>, IPositionService
    {
        /// <summary>
        /// 读取分页列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResult<GetPositionPagesResponse>> GetPagesAsync(
            GetPositionPagesRequest request)
        {
            // var rulers = GetRuler<GetPositionPagesResponse>();
            var result = await QueryNoTracking<Position>()
                .HasWhere(request.Keyword, p =>
                    p.Name.Contains(request.Keyword!) ||
                    p.Remarks.Contains(request.Keyword!))
                .Select(p => new GetPositionPagesResponse
                {
                    Id = p.Id!,
                    Created = p.Created,
                    ParentId = p.ParentId,
                    Name = p.Name,
                    Updated = p.Updated,
                    Remarks = p.Remarks,
                    Status = p.Status
                })
                .ToPageAsync(request);
            return result;
        }

        /// <summary>
        /// 读取信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<GetPositionByIdResponse> GetByIdAsync(string id)
        {
            var result = await QueryNoTracking<Position>()
                .Where(p => p.Id == id)
                //.Select(p => _mapper.Map<Position, PositionViewModel>(p))
                .Select(p => new GetPositionByIdResponse
                {
                    Id = p.Id!,
                    Name = p.Name,
                    ParentId = p.ParentId,
                    Remarks = p.Remarks,
                    Status = p.Status,
                })
                .FirstOrDefaultAsync();
            if (result == null)
            {
                throw new CoreException("找不到数据");
            }

            // 读取角色
            var roles = await QueryNoTracking<PositionRole>()
                .Where(p => p.PositionId == id)
                .Select(p => p.RoleId).ToListAsync();
            result.RoleIds.AddRange(roles);
            return result;
        }

        /// <summary>
        /// 读取树形选择框数据列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<TreeSelectViewModel>> GetTreeSelectDataAsync()
        {
            var list = await QueryNoTracking<Position>().ToListAsync();

            var result = new List<TreeSelectViewModel>();
            // 递归读取
            GetTreeChildren(list, result, "");
            return result;
        }

        /// <summary>
        /// 根据角色Id读取职位Id列表
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <returns></returns>
        public async Task<List<string>> GetIdsByRoleIdAsync(string roleId)
        {
            var result = await QueryNoTracking<PositionRole>()
                .Where(p => p.RoleId == roleId)
                .Select(p => p.PositionId)
                .ToListAsync();

            return result;
        }

        #region 私有方法

        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="results"></param>
        /// <param name="parentId"></param>
        private static void GetTreeChildren(IList<Position> entities, ICollection<TreeSelectViewModel> results,
            string? parentId)
        {
            IList<Position> result = string.IsNullOrEmpty(parentId)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parentId).ToList();

            foreach (var t1 in result)
            {
                var res = new TreeSelectViewModel
                {
                    Id = t1.Id,
                    ParentId = t1.ParentId,
                    Title = t1.Name,
                    Value = t1.Id,
                    Key = t1.Id,
                    Disabled = t1.Status == Status.Disabled,
                    IsLeaf = !string.IsNullOrEmpty(t1.ParentId)
                };
                if (entities.Any(p => p.ParentId == t1.Id))
                {
                    res.Children = new List<TreeSelectViewModel>();
                    GetTreeChildren(entities, res.Children, t1.Id);
                }

                results.Add(res);
            }
        }

        #endregion


     
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="securityContextAccessor"></param>
        /// <param name="configuration"></param>
        /// <param name="cacheManager"></param>
        /// <param name="dataPermission"></param>
        public PositionService(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor,
            IConfiguration? configuration, ICacheManager cacheManager, IDataPermission dataPermission
        ) : base(
            dbContext,
            securityContextAccessor, configuration, cacheManager, dataPermission)
        {
        }
    }
}